function Rule() {
	this.id = "";
	this.description = "";
	this.isEnabled = true;
	this.fileNameExpression = "";
	this.initialExpression = "";
	
};


var CacheDownload_Options={
	treeRules: null,
	buttonEdit: null,
	buttonDelete: null,
	
	//This array will contains a reversed array of DOM_VK
	virtualKeys: null, 

	rules: [],
	
	getRuleName: function(row) {
		return this.rules[row].id;
	}, 
	getRuleFileNameExpression: function(row) {
		return this.rules[row].fileNameExpression;
	},
	getDescription: function(row) {
		return this.rules[row].description;
	},
	getInitialExpression: function(row) {
		return this.rules[row].initialExpression;
	},
	isRuleEnabled: function(row) {
		return this.rules[row].isEnabled;
	},
	
	
	
	
	toXML : function () {
	
		//Find a better way than :
		var parser = new DOMParser();
		var dom = parser.parseFromString("<rules></rules>", "text/xml");
		var rulesXml = dom.documentElement;
		//var dom = document.implementation.createDocument("", "", null);
		//var rulesXml = dom.createElement("rules");
		
		for(var i=0; i<this.rules.length; i++) {
			var rule = this.rules[i];
			var ruleXml = dom.createElement("rule");
			ruleXml.setAttribute("id", rule.id);	
			ruleXml.setAttribute("description", rule.description);	
			ruleXml.setAttribute("isEnabled", rule.isEnabled);	
			ruleXml.setAttribute("fileNameExpression", rule.fileNameExpression);	
			ruleXml.setAttribute("initialExpression", rule.initialExpression);	
			rulesXml.appendChild(ruleXml);
		}
		
		var serializer = new XMLSerializer();
		var xml = serializer.serializeToString(dom);

		return xml;
	},
	
	
	addRules : function (string) {
	
		var parser = new DOMParser();
		if (string.length==0) {
			return;
		}
		
		var dom = parser.parseFromString(string, "text/xml");

		var table = dom; 
		var cells = table.getElementsByTagName("rule"); 
		for (var i = 0; i < cells.length; i++) { 
			var rule = new Rule();
			rule.id = cells[i].getAttribute("id"); 
			rule.description = cells[i].getAttribute("description"); 
			rule.isEnabled = cells[i].getAttribute("isEnabled"); 
			rule.fileNameExpression = cells[i].getAttribute("fileNameExpression"); 
			rule.initialExpression = cells[i].getAttribute("initialExpression"); 
			this.addRule(rule);
		}
	},
	
	
	
  // --------------------------------------------
  // nsITreeView interface properties
  treeSelection: null, // nsiTreeSelection
  treeBox: null, // The tree
  editedRowID: null, // The row currently being edited
  
  // Getters and Setters
  set rowCount(i) { throw "rowCount is a readonly property"; },
  get rowCount() { return this.rules.length; },
  
  set selection(s) { this.treeSelection = s; },
  get selection() { return this.treeSelection; },
  
  // START nsITreeView interface methods
//  canDropBeforeAfter: function(index, before) { return false; },
//  canDropOn : function(index) { return false; },
//  cycleCell : function(row, columnID) { /* do nothing */ },
  cycleHeader: function(columnID, element) {
    /* do nothing */
  },
//  drop: function(row, orientation) { /* do nothing */ return false; },
  getCellProperties: function(row, columnID, properties) { /* do nothing */ },
  getCellText: function(row, column) {
	if (column == "namecol" || column.id == "namecol") {
      return this.getRuleName(row);
    } else if (column == "descriptioncol" || column.id == "descriptioncol") {
      return this.getDescription(row);
    }
    return null;
	},
//  getCellValue: function(row, columnID) { /* return null; */ },
  getColumnProperties: function(columnID, element, properties) { /* do nothing */ },
  getImageSrc: function(rowIndex, column) {
  	if (column == "enabledcol" || column.id == "enabledcol") {
  		if (this.isRuleEnabled(rowIndex)) {
  			return "chrome://cachedownload/skin/enabled.png";
  		} else {
  			return "chrome://cachedownload/skin/disabled.png";
  		}
  	}
  	return null;
  },
//  getLevel: function(index) { return 0; },
//  getParentIndex: function(rowIndex) { return 0; },
//  getProgressMode: function(rowIndex, columnID) { /* return 0; */ },
  getRowProperties: function(rowIndex, properties) { /* do nothing */ },
//  hasNextSibling: function(rowIndex, afterIndex) { return false; },
  isContainer: function(index) { return false; },
//  isContainerEmpty: function(index) { return false; },
//  isContainerOpen: function(index) { /* return false; */ },
//  isEditable: function(rowIndex, columnID) { return false; },
  isSeparator: function(index) { return false; },
  isSorted: function(index) { /* return false; */ },
//  performAction: function(action) { /* do nothing */ },
//  performActionOnCell: function(action, rowIndex, columnID) { /* do nothing */ },
//  performActionOnRow: function(action, rowIndex) { /* do nothing */ },
//  selectionChanged: function() { /* do nothing */ },
//  setCellText: function(rowIndex, columnID, value) { /* do nothing */ },
  setTree: function(tree) { this.treeBox=tree; },
//  toggleOpenState: function(index) { /* do nothing */ },
  // END nsITreeView interface methods
    
	
  // --------------------------------------------
	
	
	
	onLoad: function() {
		//init preference accesser
		this._prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
		this._prefs = this._prefs.getBranch("extensions.cachedownload.");
		
		this.rules = [];
		
		
		var prefValue = this._prefs.getCharPref('rules');
		this.addRules(prefValue);
		
		//set checkbox with value in preference storage
		/*var widget;
		if (widget=document.getElementById("cachedownload_chbx_show")) {
			widget.setAttribute("checked", this._prefs.getBoolPref('show_statusbar_elements'));
		}

		//Previous has index 0
		//Next has index 1

		//This array will contains a int value of modifiers for each key
		this.modifiers=new Array();
		//This array will contains a dom_vk value of key pressed for each key
		this.valueKeys=new Array();
		
		this.modifiers[0]=CacheDownload_Options.modifiersString2Int(this._prefs.getCharPref('key_previous_modifiers'));
		this.valueKeys[0]=this._prefs.getCharPref('key_previous_valueKey');
		document.getElementById("cachedownload_key_prev_tb").value+=CacheDownload_Options.getStringOfKey(0);
		
		this.modifiers[1]=CacheDownload_Options.modifiersString2Int(this._prefs.getCharPref('key_next_modifiers'));
		this.valueKeys[1]=this._prefs.getCharPref('key_next_valueKey');
		document.getElementById("cachedownload_key_next_tb").value+=CacheDownload_Options.getStringOfKey(1);
		*/
		
		this.treeRules = document.getElementById("cachedownload-tree");
		this.treeRules.treeBoxObject.view = this;
		
		this.buttonEdit = document.getElementById("editButton");
		this.buttonDelete = document.getElementById("deleteButton");
		
		
		this.onSelectRule();
	},
	
	onDialogAccept: function() {
		if(!this._prefs) return;
		
		//var widget, value;

		//save rules option
		
		var value = this.toXML();
		if (value!=null && value!=undefined && value.length>0) {
			this._prefs.setCharPref('rules', value);
		}
		
		//save statusbar-buttons option
		//if ((widget=document.getElementById("cachedownload_chbx_show"))) {
		//	value=widget.getAttribute("checked")=="true";
		//	this._prefs.setBoolPref('show_statusbar_elements', value);
		//}
		
		//save previous key
		//this._prefs.setCharPref('key_previous_modifiers', CacheDownload_Options.modifiersInt2String(this.modifiers[0]));
		//this._prefs.setCharPref('key_previous_valueKey', this.valueKeys[0]?this.valueKeys[0]:"");

		//save next key
		//this._prefs.setCharPref('key_next_modifiers', CacheDownload_Options.modifiersInt2String(this.modifiers[1]));
		//this._prefs.setCharPref('key_next_valueKey', this.valueKeys[1]?this.valueKeys[1]:"");
		
		//Now, the observer linked on preference will be notified
	},
	
	onEnableRule: function() {
		var index = this.treeRules.currentIndex;
		
		if (this.treeRules.view.selection.getRangeCount()==0) {
			return;
		}
		
		this.rules[index].isEnabled=!this.rules[index].isEnabled;
		
		// Notify the treeBoxObject that a row has been edited
		this.treeRules.treeBoxObject.invalidateRow(index);
	},
	
	onSelectRule: function() {
		var hasNoSelection = this.treeRules.view.selection.getRangeCount()==0;
		this.buttonEdit.setAttribute("disabled", hasNoSelection);
		this.buttonDelete.setAttribute("disabled", hasNoSelection);
	},
	
	onDeleteRule: function() {
		
		var deleteIndex = this.treeRules.currentIndex;
		this.rules.splice(deleteIndex, 1);

		// Notify the treeBoxObject that a row has been deleted
		// Select the next row if there is one
		this.treeRules.treeBoxObject.rowCountChanged(deleteIndex, -1);
		this.treeRules.select(deleteIndex);
	},
	
	onNewRule: function() {
		let result = {};
		var rule = new Rule();
		openDialog("edit-rule.xul", "_blank", "chrome,centerscreen,modal,resizable,dialog=no", rule, result);

		if (!("status" in result))
			return;
		
		this.rules.push(rule);
		if (this.treeBox!=null) {
			// Notify the treeBoxObject that a row has been added
			// Select the next row if there is one
			this.treeBox.rowCountChanged(this.rules.length-1, 1);
			this.treeRules.select(this.rules.length-1);
		}
	},
	
	onEditRule: function() {
		var index = this.treeRules.currentIndex;
		let result = {};
		openDialog("edit-rule.xul", "_blank", "chrome,centerscreen,modal,resizable,dialog=no", this.rules[index], result);

		if (!("status" in result))
			return;
		
		this.treeRules.treeBoxObject.invalidateRow(index);
	},
	
	
	
	addRule : function(rule) {
		var contains = false;
		for(var k=0; k<this.rules.length;k++) {
			if (this.rules[k].id == rule.id) {
				contains = true;
				break;
			}
		}
			
		if (!contains) {
			this.rules.push(rule);
			
			if (this.treeBox!=null) {
				// Notify the treeBoxObject that a row has been added
				// Select the next row if there is one
				this.treeBox.rowCountChanged(this.rules.length-1, 1);
			}
		}
	},
	
	onDetectSelectionRule: function(event) {
		var tbo = this.treeRules.treeBoxObject;
		
		var row = { }, col = { }, child = { };
		tbo.getCellAt(event.clientX, event.clientY, row, col, child);
		if (row.value==-1) {
			this.treeRules.view.selection.clearSelection();
			this.onSelectRule();
		}
			
	},
	
	onLoadDefaultRules: function() {
	
		var req = new XMLHttpRequest();
		req.open("GET", "chrome://cachedownload/content/defaultRules.xml", false); 
		req.send(null);

		var rulesText = req.responseText;
		this.addRules(rulesText);
		
	},
	
	
};

